package com.siyoumi.util;

import com.google.zxing.*;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.QRCodeReader;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.siyoumi.exception.BaseExceptionHandler;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;

//生成解析，二维码
public class XQrCode
{
    private static final String BASE64_IMAGE = "data:image/png;base64,%s";

    static private String toBase64(String content, Integer width, Integer height)
    {
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        BufferedImage image = crateQRCode(content, width, height);
        try
        {
            ImageIO.write(image, "png", os);
        } catch (IOException e)
        {
            XLog.error(XQrCode.class, "[生成二维码，错误{", e.getMessage(), "}]");
        }
        // 转出即可直接使用
        return BASE64_IMAGE + XStr.base64Enc(os.toByteArray());
    }


    //生成二维码
    static public BufferedImage crateQRCode(String content, Integer width, Integer height)
    {
        if (XStr.isNullOrEmpty(content))
        {
            return null;
        }

        ServletOutputStream stream = null;
        HashMap<EncodeHintType, Comparable> hints = new HashMap<>(4);
        // 指定字符编码为utf-8
        hints.put(EncodeHintType.CHARACTER_SET, StandardCharsets.UTF_8);
        // 指定二维码的纠错等级为中级
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
        // 设置图片的边距
        hints.put(EncodeHintType.MARGIN, 1);
        try
        {
            QRCodeWriter writer = new QRCodeWriter();
            BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, width, height, hints);
            BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    bufferedImage.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
                }
            }
            return bufferedImage;
        } catch (Exception e)
        {
            BaseExceptionHandler.printStackTrace(e);
        } finally
        {
            if (stream != null)
            {
                try
                {
                    stream.flush();
                    stream.close();
                } catch (IOException e)
                {
                    BaseExceptionHandler.printStackTrace(e);;
                }
            }
        }

        return null;
    }


    //解析二维码
    static public Result readQrCode(String qrUrl) throws IOException
    {
        if (XStr.isNullOrEmpty(qrUrl))
        {
            return null;
        }

        BufferedImage img = ImageIO.read(new File(qrUrl));
        BufferedImageLuminanceSource source = new BufferedImageLuminanceSource(img);
        BinaryBitmap imgBitmap = new BinaryBitmap(new HybridBinarizer(source));

        QRCodeReader reader = new QRCodeReader();
        Result res = null;
        try
        {
            res = reader.decode(imgBitmap);
        } catch (NotFoundException e)
        {
            BaseExceptionHandler.printStackTrace(e);;
        } catch (ChecksumException e)
        {
            BaseExceptionHandler.printStackTrace(e);;
        } catch (FormatException e)
        {
            BaseExceptionHandler.printStackTrace(e);;
        }
        return res;
    }
}
